package hu.bme.orarend.client;

import hu.bme.orarend.shared.ClassDTO;
import hu.bme.orarend.shared.RoomDTO;
import hu.bme.orarend.shared.ScheduleDTO;

import java.util.ArrayList;

import org.gwt.advanced.client.ui.SelectRowListener;
import org.gwt.advanced.client.ui.widget.EditableGrid;
import org.gwt.advanced.client.util.ThemeHelper;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Orarend implements EntryPoint
{
  /**
   * The message displayed to the user when the server cannot be reached or
   * returns an error.
   */
  private static final String SERVER_ERROR = "An error occurred while "
      + "attempting to contact the server. Please check your network " + "connection and try again.";

  /**
   * Create a remote service proxy to talk to the server-side Greeting service.
   */
  private final OrarendServiceAsync orarendService = GWT.create( OrarendService.class );

  /**
   * Urlap elemek 
   */
  TextBox roomName = new TextBox();
  TextBox building = new TextBox();
  TextBox floor = new TextBox();
  TextBox door = new TextBox();
  TextBox capacity = new TextBox();
  ListBox type = new ListBox();
  CheckBox projector = new CheckBox( "Projektor" );
  CheckBox amplifier = new CheckBox( "Hangos\u00EDt\u00E1s" );

  TextBox classId = new TextBox();
  TextBox className = new TextBox();
  TextBox classDescription = new TextBox();
  TextBox classTeacher = new TextBox();
  ListBox classType = new ListBox();
  ListBox classDate = new ListBox();
  TextBox classStartTime = new TextBox();
  TextBox classNumber = new TextBox();
  CheckBox classProjector = new CheckBox( "Projektor" );
  CheckBox classAmplifier = new CheckBox( "Erősítő" );
  TextBox classEndTime = new TextBox();
  ListBox classRoom = new ListBox();
  PasswordTextBox password = new PasswordTextBox();
  TextBox userName = new TextBox();

  /**
   * This is the entry point method.
   */
  public void onModuleLoad()
  {
    ThemeHelper.getInstance().setThemeName( "classic" );
    final Label errorLabel = new Label();

    // Add the nameField and sendButton to the RootPanel
    // Use RootPanel.get() to get the entire body element
    RootPanel rootPanel = RootPanel.get( "nameFieldContainer" );
    rootPanel.getElement().getStyle().setPosition( Position.RELATIVE );
    RootPanel.get( "errorLabelContainer" ).add( errorLabel );

    final TabLayoutPanel tabLayoutPanel = new TabLayoutPanel( 1.5, Unit.EM );
    
    VerticalPanel verticalPanel = new VerticalPanel();
    tabLayoutPanel.add(verticalPanel, "Bejelentkezés", false);
    verticalPanel.setSize("511px", "130px");
    
    Label userNameLabel = new Label("Felhasználói név:");
    verticalPanel.add(userNameLabel);
    
    verticalPanel.add(userName);
    
    Label passwordLabel = new Label("Jelszó:");
    verticalPanel.add(passwordLabel);
    
    verticalPanel.add(password);
    
    Button authButton = new Button("Belép");
    verticalPanel.add(authButton);

    final VerticalPanel managingRooms = new VerticalPanel();
    managingRooms.setSize( "770px", "550px" );

    FlexTable roomForm = new FlexTable();
    managingRooms.add( roomForm );
    roomForm.setSize( "780px", "250px" );

    Label roomNameLabel = new Label( "Teremn\u00E9v:" );
    roomForm.setWidget( 0, 0, roomNameLabel );

    roomForm.setWidget( 0, 1, roomName );

    Label buildingLabel = new Label( "\u00C9p\u00FClet:" );
    roomForm.setWidget( 1, 0, buildingLabel );

    roomForm.setWidget( 1, 1, building );

    Label floorLabel = new Label( "Emelet:" );
    roomForm.setWidget( 2, 0, floorLabel );

    roomForm.setWidget( 2, 1, floor );

    Label doorLabel = new Label( "Ajt\u00F3:" );
    roomForm.setWidget( 3, 0, doorLabel );

    roomForm.setWidget( 3, 1, door );

    Label capacityLabel = new Label( "Befogad\u00F3k\u00E9pess\u00E9g:" );
    roomForm.setWidget( 4, 0, capacityLabel );

    roomForm.setWidget( 4, 1, capacity );

    Label typeLabel = new Label( "T\u00EDpus:" );
    roomForm.setWidget( 5, 0, typeLabel );

    type.addItem( RoomDTO.TYPE_0 );
    type.addItem( RoomDTO.TYPE_1 );
    type.setSelectedIndex( 0 );
    roomForm.setWidget( 5, 1, type );

    Label equipmentLabel = new Label( "Felszerelts\u00E9g:" );
    roomForm.setWidget( 6, 0, equipmentLabel );

    VerticalPanel equipmentPanel = new VerticalPanel();
    roomForm.setWidget( 6, 1, equipmentPanel );

    equipmentPanel.add( projector );

    equipmentPanel.add( amplifier );

    HorizontalPanel horizontalPanel = new HorizontalPanel();
    managingRooms.add( horizontalPanel );
    managingRooms.setCellHorizontalAlignment( horizontalPanel, HasHorizontalAlignment.ALIGN_CENTER );

    Button saveRoomButton = new Button( "Ment\u00E9s" );
    horizontalPanel.add( saveRoomButton );
    managingRooms.setCellHorizontalAlignment( saveRoomButton, HasHorizontalAlignment.ALIGN_CENTER );

    Button refreshRoomsButton = new Button( "Frissít" );
    horizontalPanel.add( refreshRoomsButton );
    horizontalPanel.setCellHorizontalAlignment( refreshRoomsButton, HasHorizontalAlignment.ALIGN_CENTER );

    final RoomGridPanel roomGridPanel = new RoomGridPanel();
    roomGridPanel.createRoomGrid();
    managingRooms.add( roomGridPanel );
    managingRooms.setCellHorizontalAlignment( roomGridPanel, HasHorizontalAlignment.ALIGN_CENTER );
    refreshRoomsButton.addClickHandler( new ClickHandler()
    {
      public void onClick( ClickEvent event )
      {
        orarendService.getRoomList( new AsyncCallback<ArrayList<RoomDTO>>()
        {
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );

          }

          @Override
          public void onSuccess( ArrayList<RoomDTO> result )
          {
            roomGridPanel.refreshData( result );
            classRoom = new ListBox();
            classRoom.addItem( "" );
            for( RoomDTO roomDTO : result )
            {
              classRoom.addItem( roomDTO.getName() );
            }
          }
        } );
      }
    } );

    roomGridPanel.addSelectRowListener( new RoomGridSelectRowListener() );

    final VerticalPanel managingClasses = new VerticalPanel();
    managingClasses.setSize( "770px", "550px" );

    FlexTable classForm = new FlexTable();
    managingClasses.add( classForm );
    classForm.setSize( "780px", "250px" );

    Label classIdLabel = new Label( "Tárgy azonosító:" );
    classForm.setWidget( 0, 0, classIdLabel );

    classId.setReadOnly( true );
    classForm.setWidget( 0, 1, classId );

    Label classNameLabel = new Label( "Tárgy neve:" );
    classForm.setWidget( 1, 0, classNameLabel );

    classForm.setWidget( 1, 1, className );

    Label classDescriptionLabel = new Label( "Tárgy leírása:" );
    classForm.setWidget( 2, 0, classDescriptionLabel );

    classForm.setWidget( 2, 1, classDescription );

    Label classTeacherLabel = new Label( "Tanár:" );
    classForm.setWidget( 3, 0, classTeacherLabel );

    classForm.setWidget( 3, 1, classTeacher );

    Label classTypeLabel = new Label( "Típus:" );
    classForm.setWidget( 4, 0, classTypeLabel );

    classType.addItem( RoomDTO.TYPE_0, "0" );
    classType.addItem( RoomDTO.TYPE_1, "1" );
    classType.setSelectedIndex( 0 );
    classForm.setWidget( 4, 1, classType );

    Label classDayLabel = new Label( "Nap:" );
    classForm.setWidget( 5, 0, classDayLabel );

    classDate.addItem( ClassDTO.MON_VAL );
    classDate.addItem( ClassDTO.TUE_VAL );
    classDate.addItem( ClassDTO.WED_VAL );
    classDate.addItem( ClassDTO.THU_VAL );
    classDate.addItem( ClassDTO.FRI_VAL );
    classDate.addItem( ClassDTO.SAT_VAL );
    classDate.addItem( ClassDTO.SUN_VAL );
    classForm.setWidget( 5, 1, classDate );

    Label classTime = new Label( "Kezdő időpont (óó:pp):" );
    classForm.setWidget( 6, 0, classTime );

    classForm.setWidget( 6, 1, classStartTime );

    Label lblVgsIdpontpp = new Label( "Végső időpont (óó:pp):" );
    classForm.setWidget( 7, 0, lblVgsIdpontpp );

    classForm.setWidget( 7, 1, classEndTime );

    Label classNumberLabel = new Label( "Létszám:" );
    classForm.setWidget( 8, 0, classNumberLabel );

    classForm.setWidget( 8, 1, classNumber );

    Label classEquipmentLabel = new Label( "Felszereltség igény:" );
    classForm.setWidget( 9, 0, classEquipmentLabel );

    VerticalPanel classEquipmentPanel = new VerticalPanel();
    classForm.setWidget( 9, 1, classEquipmentPanel );

    classEquipmentPanel.add( classProjector );

    classEquipmentPanel.add( classAmplifier );

    Label classRoomLabel = new Label( "Fix terem:" );
    classForm.setWidget( 10, 0, classRoomLabel );

    classRoom.addItem( "" );
    classRoom.setSelectedIndex( 0 );
    classForm.setWidget( 10, 1, classRoom );

    final ClassGridPanel classGridPanel = new ClassGridPanel();
    classGridPanel.createClassGrid();

    HorizontalPanel buttonPanel = new HorizontalPanel();
    managingClasses.add( buttonPanel );
    managingClasses.setCellHorizontalAlignment( buttonPanel, HasHorizontalAlignment.ALIGN_CENTER );

    Button saveClassButton = new Button( "Mentés" );
    buttonPanel.add( saveClassButton );
    buttonPanel.setCellHorizontalAlignment( saveClassButton, HasHorizontalAlignment.ALIGN_CENTER );
    saveRoomButton.addClickHandler(new ClickHandler()
    {
      public void onClick(ClickEvent event)
      {
        RoomDTO roomDTO = new RoomDTO();
        try
        {
          roomDTO.setName( roomName.getText() );
          roomDTO.setBuilding( building.getText() );
          roomDTO.setFloor( floor.getText() );
          roomDTO.setDoor( door.getText() );
          roomDTO.setCapacity( Integer.valueOf( capacity.getText() ) );
          roomDTO.setType( String.valueOf( type.getSelectedIndex() ) );
          roomDTO.setAmplifier( amplifier.getValue() );
          roomDTO.setProjector( projector.getValue() );
        orarendService.saveRoom( roomDTO, new AsyncCallback<Boolean>()
        {
          @Override
          public void onSuccess( Boolean result )
          {
            orarendService.getRoomList( new AsyncCallback<ArrayList<RoomDTO>>()
                {
              @Override
              public void onFailure( Throwable caught )
              {
                Window.alert( caught.getMessage() );
                
              }
              
              @Override
              public void onSuccess( ArrayList<RoomDTO> result )
              {
                roomGridPanel.refreshData( result );        
              }
                });
          }
          
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );            
          }
        });
        }
        catch (Exception e)
        {
          Window.alert( "Hibás teremkapacitás!" );
        }
      }
    });
    saveClassButton.addClickHandler( new ClickHandler()
    {
      public void onClick( ClickEvent event )
      {
        try
        {
          ClassDTO classDTO = new ClassDTO();
          classDTO.setId( classId.getText().isEmpty() ? 0 : Integer.valueOf( classId.getText() ) );
          classDTO.setName( className.getText() );
          classDTO.setDescription( classDescription.getText() );
          classDTO.setTeacher( classTeacher.getText() );
          classDTO.setRoomType( classType.getValue( classType.getSelectedIndex() ) );
          classDTO.setDay( classDate.getItemText( classDate.getSelectedIndex() ) );
          classDTO.setStart( classStartTime.getText() );
          classDTO.setEnd( classEndTime.getText() );
          classDTO.setNumber( Integer.valueOf( classNumber.getText() ) );
          classDTO.setProjector( classProjector.getValue() );
          classDTO.setAmplifier( classAmplifier.getValue() );
          classDTO.setRoom( classRoom.getItemText( classRoom.getSelectedIndex() ) );
          orarendService.saveClass( classDTO, new AsyncCallback<Boolean>()
          {
  
            @Override
            public void onFailure( Throwable caught )
            {
              Window.alert( caught.getMessage() );
            }
  
            @Override
            public void onSuccess( Boolean result )
            {
              orarendService.getClassList( new AsyncCallback<ArrayList<ClassDTO>>()
              {
                @Override
                public void onFailure( Throwable caught )
                {
                  Window.alert( caught.getMessage() );
                }
  
                @Override
                public void onSuccess( ArrayList<ClassDTO> result )
                {
                  classGridPanel.refreshData( result );
                }
              } );
            }
  
          } );
        }
        catch (Exception e)
        {
          Window.alert( "Hibás létszám!" );
        }
      }
    } );
    managingClasses.setCellHorizontalAlignment( saveClassButton, HasHorizontalAlignment.ALIGN_CENTER );

    Button refreshClassesButton = new Button( "Frissít" );
    buttonPanel.add( refreshClassesButton );
    refreshClassesButton.addClickHandler( new ClickHandler()
    {
      public void onClick( ClickEvent event )
      {
        orarendService.getClassList( new AsyncCallback<ArrayList<ClassDTO>>()
        {
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );
          }

          @Override
          public void onSuccess( ArrayList<ClassDTO> result )
          {
            classGridPanel.refreshData( result );
          }
        } );
      }
    } );
    managingClasses.setCellHorizontalAlignment( refreshClassesButton, HasHorizontalAlignment.ALIGN_CENTER );
    
    Button resetClassButton = new Button("Form törlése");
    resetClassButton.addClickHandler(new ClickHandler()
    {
      public void onClick(ClickEvent event)
      {
        classId.setText( "" );
        className.setText( "" );
        classDescription.setText( "" );
        classTeacher.setText( "" );
        classType.setSelectedIndex( 0 );
        classDate.getItemText( 0 );
        classStartTime.setText( "" );
        classEndTime.setText( "" );
        classNumber.setText( "" );
        classProjector.setValue( false );
        classAmplifier.setValue( false );
        classRoom.setSelectedIndex( 0 );
      }
    });
    buttonPanel.add(resetClassButton);
    managingClasses.add( classGridPanel );
    managingClasses.setCellHorizontalAlignment( classGridPanel, HasHorizontalAlignment.ALIGN_CENTER );
    
    final SimplePanel generatePanel = new SimplePanel();
    
    Button btnGenerls = new Button("Generálás");
    btnGenerls.addClickHandler(new ClickHandler()
    {
      public void onClick(ClickEvent event)
      {
        orarendService.createSchedule( new AsyncCallback<Integer>()
        {
          
          @Override
          public void onSuccess( Integer result )
          {
            Window.alert( "Az órarend sikeresen elkészült!" );
          }
          
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );
          }
        });
      }
    });
    generatePanel.setWidget(btnGenerls);
    btnGenerls.setSize("400px", "200px");
    
    VerticalPanel schedulePanel = new VerticalPanel();
    schedulePanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    tabLayoutPanel.add(schedulePanel, "Órarend", false);
    schedulePanel.setSize("858px", "595px");
    
    Label scheduleLabel = new Label("Órarend:");
    schedulePanel.add(scheduleLabel);
    
    Button refreshScheduleButton = new Button("Lekérés/Frissítés");
    schedulePanel.add(refreshScheduleButton);
    
    final ScheduleGridPanel scheduleGridPanel = new ScheduleGridPanel();
    scheduleGridPanel.createClassGrid();
    schedulePanel.add( scheduleGridPanel );
    
    Label leftClassesLabel = new Label("Kimaradt órák:");
    schedulePanel.add(leftClassesLabel);
    
    Button leftClassesButton = new Button("Lekérés/Frissítés");
    schedulePanel.add(leftClassesButton);
    
    final ClassGridPanel leftClassesGridPanel = new ClassGridPanel();
    leftClassesGridPanel.createClassGrid();
    schedulePanel.add( leftClassesGridPanel );

    authButton.addClickHandler(new ClickHandler()
    {      
      public void onClick(ClickEvent event)
      {
        orarendService.authUser( userName.getText(), password.getText(), new AsyncCallback<Boolean>()
            {
          
          @Override
          public void onSuccess( Boolean result )
          {
            if( result )
            {
              tabLayoutPanel.add( managingRooms, "Teremkarbantart\u00E1s", false );
              tabLayoutPanel.add( managingClasses, "Tantárgyak", false );
              tabLayoutPanel.add( generatePanel, "Generálás", false);
            }
            else
              Window.alert( "Hibás felhasználónév vagy jelszó!" );
          }
          
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );            
          }
            });
      }
    });

    
    leftClassesButton.addClickHandler(new ClickHandler()
    {
      public void onClick(ClickEvent event)
      {
        orarendService.getLeftClassesList( new AsyncCallback<ArrayList<ClassDTO>>()
        {
          @Override
          public void onSuccess( ArrayList<ClassDTO> result )
          {
            leftClassesGridPanel.refreshData( result );
          }
          
          @Override
          public void onFailure( Throwable caught )
          {
            Window.alert( caught.getMessage() );
          }
        });
      }
    });
    refreshScheduleButton.addClickHandler(new ClickHandler()
    {
      public void onClick(ClickEvent event)
      {
        orarendService.getScheduleList( new AsyncCallback<ArrayList<ScheduleDTO>>()
        {
          
          @Override
          public void onSuccess( ArrayList<ScheduleDTO> result )
          {
            scheduleGridPanel.refreshData( result );            
          }
          
          @Override
          public void onFailure( Throwable caught )
          {
            // TODO Auto-generated method stub
          }
        });
      }
    });
    
    classGridPanel.addSelectRowListener( new ClassGridSelectRowListener() );

    orarendService.getRoomList( new AsyncCallback<ArrayList<RoomDTO>>()
    {
      @Override
      public void onFailure( Throwable caught )
      {
        Window.alert( caught.getMessage() );
      }

      @Override
      public void onSuccess( ArrayList<RoomDTO> result )
      {
        roomGridPanel.refreshData( result );
        for( RoomDTO roomDTO : result )
        {
          classRoom.addItem( roomDTO.getName() );
          
        }
      }
    } );

    //roomGridPanel.addSelectRowListener( new RoomGridSelectRowListener() );

    orarendService.getClassList( new AsyncCallback<ArrayList<ClassDTO>>()
    {
      @Override
      public void onFailure( Throwable caught )
      {
        Window.alert( caught.getMessage() );
      }

      @Override
      public void onSuccess( ArrayList<ClassDTO> result )
      {
        classGridPanel.refreshData( result );
      }
    } );
    rootPanel.add( tabLayoutPanel, 12, 10 );
    tabLayoutPanel.setSize( "881px", "629px" );
  }

  private class RoomGridSelectRowListener implements SelectRowListener
  {

    @Override
    public void onSelect( EditableGrid grid, int row )
    {
      roomName.setText( grid.getText( row, 0 ) );
      building.setText( grid.getText( row, 1 ) );
      floor.setText( grid.getText( row, 2 ) );
      door.setText( grid.getText( row, 3 ) );
      capacity.setText( grid.getText( row, 4 ) );
      type.setSelectedIndex( ( RoomDTO.TYPE_0.equals( grid.getText( row, 5 ) ) ) ? 0 : 1 );
      projector.setValue( ( RoomDTO.YES.equals( grid.getText( row, 6 ) ) ) ? true : false );
      amplifier.setValue( ( RoomDTO.YES.equals( grid.getText( row, 7 ) ) ) ? true : false );
    }
  }

  private class ClassGridSelectRowListener implements SelectRowListener
  {

    @Override
    public void onSelect( EditableGrid grid, int row )
    {
      classId.setText( grid.getText( row, 0 ) );
      className.setText( grid.getText( row, 1 ) );
      classDescription.setText( grid.getText( row, 2 ) );
      classTeacher.setText( grid.getText( row, 3 ) );
      classType.setSelectedIndex( ( RoomDTO.TYPE_0.equals( grid.getText( row, 4 ) ) ) ? 0 : 1 );
      for( int i = 0; i <= 6; i++ )
      {
        if( classDate.getItemText( i ).equals( grid.getText( row, 5 ) ) )
          classDate.setSelectedIndex( i );
      }
      classStartTime.setText( grid.getText( row, 6 ) );
      classEndTime.setText( grid.getText( row, 7 ) );
      classNumber.setText( grid.getText( row, 8 ) );
      classProjector.setValue( ( RoomDTO.YES.equals( grid.getText( row, 9 ) ) ) ? true : false );
      classAmplifier.setValue( ( RoomDTO.YES.equals( grid.getText( row, 10 ) ) ) ? true : false );
      for( int i = 1; i < classRoom.getItemCount(); i++)
      {
        if( classRoom.getItemText( i ).equals( grid.getText( row, 11 ) ) )
          classRoom.setSelectedIndex( i );
      }
    }
  }
}
